package game;

import game.dungeon.CompositeDungeon;
import game.dungeon.Level;
import game.dungeon.Shaft;
import game.dungeon.position.Coordinate;
import game.dungeon.position.CoordinateType;
import game.dungeon.position.Direction;
import game.dungeon.position.Position;
import game.square.CommonSquare;
import game.square.Door;
import game.square.SquareImpl;
import game.square.TeleportationSquare;
import game.square.Wall;

//

/**
 * The main class of this role play game, that is used to run the program.
 * 
 * @version 1.0
 * @author Chris Desomer, Geert Heyman
 */
public class Game {
	
	public static void main (String[] args){
		CompositeDungeon<SquareImpl> mainDungeon = new CompositeDungeon<SquareImpl>(new Position(100, 200, 300));
		Level<SquareImpl> level = new Level<SquareImpl>(new Position(5,0,10),new Coordinate(10,CoordinateType.ZCOORDINATE));
		Shaft<SquareImpl> shaft = new Shaft<SquareImpl>(new Position(10, 0, 10),
				new Coordinate[] {
						null,
						new Coordinate(0, CoordinateType.YCOORDINATE),
						new Coordinate(10, CoordinateType.ZCOORDINATE) });
		addDungeons(mainDungeon, level, shaft);
		addSquaresToLevel(mainDungeon);	
		addSquaresToShaft(mainDungeon);
		printReachabilityFromLevelToShaft(level, shaft);
		System.out.println("_____________");
		printReachabilityFromShaftToLevel(shaft, level);
		System.out.println("_____________");
		printRandomTeleportationFromShaftToLevel(shaft,level);
	}
	
	private static void printRandomTeleportationFromShaftToLevel(
			Shaft<SquareImpl> shaft, Level<SquareImpl> level) {
		TeleportationSquare teleportationSquare = ((TeleportationSquare) shaft
				.getSquareAtPosition(new Position(0, 0, 10)));
		System.out.println("Teleported from \n"+ "   " + teleportationSquare+"\n to \n"+ "   " + teleportationSquare.teleport());
	}

	private static void printReachabilityFromShaftToLevel(
			Shaft<SquareImpl> shaft, Level<SquareImpl> level) {
		for (SquareImpl shaftSquare : shaft.getSquares().values())
			for (SquareImpl levelSquare: level.getSquares().values())
				System.out.println("Shaft  square: \n" + "   " + levelSquare
						+ "\n can reach level square: \n" + "   " + shaftSquare + "\n = "
						+ shaftSquare.canReachSquare(levelSquare) + "\n" );
	}

	private static void printReachabilityFromLevelToShaft(
			Level<SquareImpl> level, Shaft<SquareImpl> shaft) {
		for (SquareImpl levelSquare : level.getSquares().values())
			for (SquareImpl shaftSquare: shaft.getSquares().values())
				System.out.println("Level  square: \n" + "   " + levelSquare
						+ "\n can reach shaft square: \n" + "   " + shaftSquare + "\n = "
						+ levelSquare.canReachSquare(shaftSquare) + "\n" );
	}

	private static void addSquaresToShaft(CompositeDungeon<SquareImpl> mainDungeon) {
		CommonSquare shaftSquare = new CommonSquare();
		shaftSquare.addTeleportationDestination(mainDungeon.getSquareAtPosition(new Position(5,0,11)));
		mainDungeon.addSquareAtPosition(shaftSquare, new Position(6, 0, 11));
	}

	private static void addSquaresToLevel(CompositeDungeon<SquareImpl> mainDungeon) {
		CommonSquare square0_0_11 = new CommonSquare();
		square0_0_11.addBorderInDirection(new Door(), Direction.EAST);
		CommonSquare square1_0_11 = new CommonSquare();
		square1_0_11.addBorderInDirection(new Door(), Direction.EAST);
		CommonSquare square2_0_11 = new CommonSquare();
		square2_0_11.addBorderInDirection(new Door(), Direction.EAST);
		CommonSquare square3_0_11 = new CommonSquare();
		square3_0_11.addBorderInDirection(new Door(), Direction.EAST);
		CommonSquare square4_0_11 = new CommonSquare();
		square4_0_11.addBorderInDirection(new Door(), Direction.EAST);
		CommonSquare square5_0_11 = new CommonSquare();
		square5_0_11.addBorderInDirection(new Wall(false), Direction.EAST);
		mainDungeon.addSquareAtPosition(square0_0_11, new Position(0, 0, 11));
		mainDungeon.addSquareAtPosition(square1_0_11, new Position(1, 0, 11));
		mainDungeon.addSquareAtPosition(square2_0_11, new Position(2, 0, 11));
		mainDungeon.addSquareAtPosition(square3_0_11, new Position(3, 0, 11));
		mainDungeon.addSquareAtPosition(square4_0_11, new Position(4, 0, 11));
		mainDungeon.addSquareAtPosition(square5_0_11, new Position(5, 0, 11));
		((Door)square0_0_11.getBorderInDirection(Direction.EAST)).open();
		((Door)square1_0_11.getBorderInDirection(Direction.EAST)).open();
		((Door)square2_0_11.getBorderInDirection(Direction.EAST)).open();
		((Door)square3_0_11.getBorderInDirection(Direction.EAST)).open();
		((Door)square4_0_11.getBorderInDirection(Direction.EAST)).open();
	}

	private static void addDungeons(CompositeDungeon<SquareImpl> mainDungeon, Level<SquareImpl> level, Shaft<SquareImpl> shaft){
		mainDungeon.addSubDungeon(level, new Position(0, 0, 1));
		mainDungeon.addSubDungeon(shaft, new Position(6, 0, 1));
	}

}
